package com.kyc.kycxkplaygame.view.digital;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.kyc.kycxkplaygame.R;
import com.kyc.kycxkplaygame.activity.digital.DigitalMainActivity;
import com.kyc.kycxkplaygame.entity.digital.DigitalBlockUnit;
import com.kyc.kycxkplaygame.entity.digital.DigitalTetrisBlock;
import com.kyc.kycxkplaygame.util.erluosifangkuai.GameConfig;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Administrator on 2018/7/16.
 */

public class DigitalViewAW extends View {
    /**
     * 网格开始坐标值，横纵坐标的开始值都是此值
     */
    public static final int beginPoint = 10;
    /**
     * 俄罗斯方块的最大坐标
     */
    private static int max_x, max_y;
    /**
     * 行数和列数
     */
    private static int num_x = 0, num_y = 0;
    /**
     * 背景墙画笔
     */
    private static Paint paintWall = null;
    /**
     * 俄罗斯方块的单元块画笔
     */
    private static Paint paintBlock = null;
    private static Paint paintText = null;
    private static final int BOUND_WIDTH_OF_WALL = 1;
    /**
     * 当前正在下落的方块
     */
    private List<DigitalBlockUnit> blockUnits = new ArrayList<DigitalBlockUnit>();
    /**
     * 下一个要显示的方块
     */
    private List<DigitalBlockUnit> blockUnitBufs = new ArrayList<DigitalBlockUnit>();
    /**
     * 下一个要显示的方块
     */
    private List<DigitalBlockUnit> routeBlockUnitBufs = new ArrayList<DigitalBlockUnit>();
    /**
     * 全部的方块allBlockUnits
     */
    private List<DigitalBlockUnit> allBlockUnits = new ArrayList<DigitalBlockUnit>();
    /**
     * 单个可移动方块
     */
    private List<DigitalBlockUnit> oneBlockUnits = new ArrayList<DigitalBlockUnit>();
    /**
     * 单个移动之后的方块
     */
    private List<DigitalBlockUnit> oneMoveBlockUnits = new ArrayList<DigitalBlockUnit>();
    /**
     * 调用此对象的Activity对象
     */
    private DigitalMainActivity father = null;
    private int[] map = new int[100]; // 保存每行网格中包含俄罗斯方块单元的个数
    /**
     * 游戏的主线程
     */
    private Thread mainThread = null;
    // 游戏的几种状态
    /**
     * 标识游戏是开始还是停止
     */
    private boolean gameStatus = false;
    /**
     * 标识游戏是暂停还是运行
     */
    private boolean runningStatus = false;
    /**
     * 俄罗斯方块颜色数组
     */
    //private static final int color[] = { Color.parseColor("#FF6600"), Color.BLUE, Color.RED, Color.GREEN, Color.GRAY };
    private static final int color[] = {R.color.c_ffa4c0,
            R.color.c75cf3,
            R.color.c_0c36d2,
            R.color.c_f60fcd,
            R.color.c_2bd0d6,
            R.color.c_1fac7f,
            R.color.f54a15,
            R.color.c_5f9d0e,
            R.color.c_2095f2,
            R.color.c_ffee9900,
            R.color.colorRed};
    /**
     * 方块的中心方块单元的坐标,
     */
    private int xx, yy;
    /**
     * 方块,用户随机获取各种形状的方块
     */
    private DigitalTetrisBlock tetrisBlock;
    /**
     * 分数
     */
    private int score = 0;
    private int lastX;
    private int lastY;

    /**
     * 当前方块的类型
     */
    //private int blockType = 0;
    public DigitalViewAW(Context context) {
        this(context, null);
    }

    public DigitalViewAW(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (paintWall == null) {// 初始化化背景墙画笔
            paintWall = new Paint();
            paintWall.setColor(Color.LTGRAY);
            paintWall.setStyle(Paint.Style.STROKE);
            paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL + 1);
        }
        if (paintBlock == null) {// 初始化化背景墙画笔
            paintBlock = new Paint();
            paintBlock.setColor(Color.parseColor("#FF6600"));
        }

        if (paintText == null) {
            paintText = new Paint();
            paintText.setColor(getResources().getColor(R.color.white));
            paintText.setStyle(Paint.Style.FILL);
            paintText.setTextSize(80);
            paintText.setTextAlign(Paint.Align.CENTER);
        }
        tetrisBlock = new DigitalTetrisBlock();
        DigitalTetrisBlock.EblockType eblockType = DigitalTetrisBlock.EblockType.BLOCK_TYPE_ZERO;
        routeBlockUnitBufs = tetrisBlock.getUnits(beginPoint, beginPoint, eblockType);
        Arrays.fill(map, 0); // 每行网格中包含俄罗斯方块单元的个数全部初始化为0
        // 绘制方块
    }

    /**
     * 设置当前游戏页面的父类activity
     *
     * @param digitalMainActivity
     */
    public void setFather(DigitalMainActivity digitalMainActivity) {
        father = digitalMainActivity;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        max_x = getWidth();
        max_y = getHeight();
        RectF rel;
        // 绘制网格
        num_x = 0;
        num_y = 0;
        for (int i = beginPoint; i < max_x - DigitalBlockUnit.UNIT_SIZE; i += DigitalBlockUnit.UNIT_SIZE) {
            for (int j = beginPoint; j < max_y - DigitalBlockUnit.UNIT_SIZE; j += DigitalBlockUnit.UNIT_SIZE) {
                rel = new RectF(i, j, i + DigitalBlockUnit.UNIT_SIZE, j + DigitalBlockUnit.UNIT_SIZE);
                canvas.drawRoundRect(rel, 8, 8, paintWall);
                num_y++;
            }
            num_x++;
        }
        // 随机产生一个俄罗斯方块
        int len = blockUnits.size();
        // 绘制方块
        // Toast.makeText(context, "" + len, Toast.LENGTH_SHORT).show();
        for (int i = 0; i < len; i++) {
            int x = blockUnits.get(i).x;
            int y = blockUnits.get(i).y;
            // 设置当前方块的颜色
            paintBlock.setColor(/*color[*/getResources().getColor(blockUnits.get(i).color)/*]*/);
            rel = new RectF(x + BOUND_WIDTH_OF_WALL, y + BOUND_WIDTH_OF_WALL,
                    x + DigitalBlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL, y + DigitalBlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL);
            canvas.drawRoundRect(rel, 8, 8, paintBlock);

            Paint.FontMetrics fontMetrics = paintText.getFontMetrics();
            float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
            float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom

            int baseLineY = (int) (rel.centerY() - top / 2 - bottom / 2);//基线中间点的y轴计算公式

            canvas.drawText(blockUnits.get(i).blockTxt, rel.centerX(), baseLineY, paintText);
        }
        // 随机产生一个俄罗斯方块
        len = allBlockUnits.size();
        // 绘制方块
        // Toast.makeText(context, "" + len, Toast.LENGTH_SHORT).show();
        for (int i = 0; i < len; i++) {
            int x = allBlockUnits.get(i).x;
            int y = allBlockUnits.get(i).y;
            paintBlock.setColor(/*color[*/getResources().getColor(allBlockUnits.get(i).color)/*]*/);
            rel = new RectF(x + BOUND_WIDTH_OF_WALL, y + BOUND_WIDTH_OF_WALL,
                    x + DigitalBlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL, y + DigitalBlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL);
            canvas.drawRoundRect(rel, 8, 8, paintBlock);

            Paint.FontMetrics fontMetrics = paintText.getFontMetrics();
            float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
            float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom

            int baseLineY = (int) (rel.centerY() - top / 2 - bottom / 2);//基线中间点的y轴计算公式

            canvas.drawText(allBlockUnits.get(i).blockTxt, rel.centerX(), baseLineY, paintText);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                Log.i("KYCC","lastX === "+ lastX + "  ,  lastY ==== " +lastY);
                if (!DigitalBlockUnit.canMoveToDown(blockUnits, max_y, allBlockUnits)) {
                    for (DigitalBlockUnit blockUnit : allBlockUnits) {
                        /*lastX = blockUnit.x;
                        lastY = blockUnit.y;*/
                        int left = blockUnit.x;
                        int right = blockUnit.x + DigitalBlockUnit.UNIT_SIZE;
                        int top = blockUnit.y;
                        int bottom = blockUnit.y + DigitalBlockUnit.UNIT_SIZE;
                        if(lastX > left && lastX < right && lastY > top && lastY < bottom) {
                            Log.i("KYCC","block   x === "+ blockUnit.x + "  ,  y ==== " +blockUnit.y);
                            oneBlockUnits.add(blockUnit);
                        }
                    }
                }

                break;
            case MotionEvent.ACTION_MOVE:
                int dx = (int) event.getRawX() - lastX ;
                int dy = (int) event.getRawY() - lastY;
                Log.i("KYCC","dx === "+ dx + "  ,  dy ==== " +dy);
                for (DigitalBlockUnit blockUnit : oneBlockUnits) {
                    int left = blockUnit.x + dx;
                    int top = blockUnit.y + dy;
                    int right = blockUnit.x + DigitalBlockUnit.UNIT_SIZE + dx;
                    int bottom = blockUnit.y + DigitalBlockUnit.UNIT_SIZE + dy;
                    if (left < (DigitalBlockUnit.UNIT_SIZE / 2)) {
                        left = blockUnit.x;
                        right = left + DigitalBlockUnit.UNIT_SIZE;
                    }
                    if (right > max_x) {
                        right = max_x;
                        left = right - DigitalBlockUnit.UNIT_SIZE;//getWidth();
                    }
                    if (top < (DigitalBlockUnit.UNIT_SIZE / 2)) {
                        top = blockUnit.y;
                        bottom = top + DigitalBlockUnit.UNIT_SIZE;//getHeight();
                    }
                    if (bottom > max_y) {
                        bottom = max_y;
                        top = bottom - DigitalBlockUnit.UNIT_SIZE;//getHeight();
                    }
                    oneMoveBlockUnits.add(new DigitalBlockUnit(left,top,blockUnit.color,blockUnit.blockTxt));
                    //layout(left, top, right, bottom);
                    DigitalBlockUnit.removeBlock(allBlockUnits,blockUnit);
                    DigitalBlockUnit.toMove(oneMoveBlockUnits,max_x,allBlockUnits);
                }

                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_UP:
                oneBlockUnits.clear();
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * 开始游戏
     */
    public void startGame() {
        gameStatus = true;
        runningStatus = true;
        if (mainThread == null || !mainThread.isAlive()) {
            getNewBlock();
            mainThread = new Thread(new MainThread());
            mainThread.start();
        }

    }

    /**
     * 暂停游戏
     */
    public void pauseGame() {
        runningStatus = false;
    }

    /**
     * 继续游戏
     */
    public void continueGame() {
        runningStatus = true;
    }

    /**
     * 停止游戏
     */
    public void stopGame() {
        // 停止游戏,释放游戏主线程
        runningStatus = false;
        gameStatus = false;
        mainThread.interrupt();
        blockUnits.clear();
        allBlockUnits.clear();
        score = 0;
        invalidate();
    }

    /**
     * 向左滑动
     */
    public void toLeft() {
        if (DigitalBlockUnit.toLeft(blockUnits, max_x, allBlockUnits)) {
            xx = xx - DigitalBlockUnit.UNIT_SIZE;
        }
        invalidate();
    }

    /**
     * 向右滑动
     */
    public void toRight() {
        if (DigitalBlockUnit.toRight(blockUnits, max_x, allBlockUnits)) {
            xx = xx + DigitalBlockUnit.UNIT_SIZE;
        }
        invalidate();
    }

    /**
     * 按顺时针旋转
     */
    public void route() {
        /*if (blockType == 3) {// 如果当前正在下落的方块为正方形,则不进行旋转
            return;
        }*/
        if (routeBlockUnitBufs.size() != blockUnits.size()) {
            DigitalTetrisBlock.EblockType eblockType = DigitalTetrisBlock.EblockType.BLOCK_TYPE_ZERO;
            routeBlockUnitBufs = tetrisBlock.getUnits(xx, yy, eblockType);
        }
        for (int i = 0; i < blockUnits.size(); i++) {
            routeBlockUnitBufs.get(i).x = blockUnits.get(i).x;
            routeBlockUnitBufs.get(i).y = blockUnits.get(i).y;
        }
        for (DigitalBlockUnit blockUnit : routeBlockUnitBufs) {
            int tx = blockUnit.x;
            int ty = blockUnit.y;
            blockUnit.x = -(ty - yy) + xx;
            blockUnit.y = tx - xx + yy;
        }
        routeTran(routeBlockUnitBufs);
        if (!DigitalBlockUnit.canRoute(routeBlockUnitBufs, allBlockUnits)) {
            // Toast.makeText(father, "不可旋转", Toast.LENGTH_SHORT).show();
            return;
        }
        for (DigitalBlockUnit blockUnit : blockUnits) {
            int tx = blockUnit.x;
            int ty = blockUnit.y;
            blockUnit.x = -(ty - yy) + xx;
            blockUnit.y = tx - xx + yy;
        }
        routeTran(blockUnits);
        invalidate();
    }

    /**
     * 如果方块处于边缘,则翻转过后,会出现方块部分处于边缘之外的情况, 因此,通过递归判断是否有超出边缘的部分,
     * 如果有,则进行左右平移,把处于边缘外的方块移动到边缘内
     */
    public void routeTran(List<DigitalBlockUnit> blockUnitsBuf) {
        boolean needLeftTran = false;
        boolean needRightTran = false;
        for (DigitalBlockUnit u : blockUnitsBuf) {
            if (u.x < beginPoint) {
                needLeftTran = true;
            }
            if (u.x > max_x - DigitalBlockUnit.UNIT_SIZE) {
                needRightTran = true;
            }
        }
        if (needLeftTran || needRightTran) {
            for (DigitalBlockUnit u : blockUnitsBuf) {
                if (needLeftTran) {
                    u.x = u.x + DigitalBlockUnit.UNIT_SIZE;
                } else if (needRightTran) {
                    u.x = u.x - DigitalBlockUnit.UNIT_SIZE;
                }
            }
            routeTran(blockUnitsBuf);
        } else {
            return;
        }

    }

    /**
     * 获取一个新的方块
     */
    private void getNewBlock() {
        // 新的方块的坐标，x坐标位于x轴的中间，y 位于起始位置
        this.xx = beginPoint + (4 / 2) * DigitalBlockUnit.UNIT_SIZE;
        this.yy = beginPoint;
        if (blockUnitBufs.size() == 0) {
            // 当游戏第一次开始的时候，先初始化一个方块
            DigitalTetrisBlock.EblockType eblockType = DigitalTetrisBlock.EblockType.BLOCK_TYPE_ZERO;
            blockUnitBufs = tetrisBlock.getUnits(xx, yy, eblockType);
        }
        blockUnits = blockUnitBufs;
        DigitalTetrisBlock.EblockType eblockType = DigitalTetrisBlock.EblockType.BLOCK_TYPE_ZERO;
        blockUnitBufs = tetrisBlock.getUnits(xx, yy, eblockType);


        //blockType = tetrisBlock.blockType;

       /* if (father != null) {// 显示出下一个要出现的方块
            father.setNextBlockView(blockUnitBufs, (num_x / 2) * DigitalBlockUnit.UNIT_SIZE);
        }*/


    }

    /**
     * 游戏的主线程
     *
     * @sign Created by wang.ao on 2017年1月16日
     */
    private class MainThread implements Runnable {

        @Override
        public void run() {
            while (gameStatus) {
                while (runningStatus) {
                    if (DigitalBlockUnit.canMoveToDown(blockUnits, max_y, allBlockUnits)) {
                        // 判断是否可以继续下落，如果可以下落，则下落
                        DigitalBlockUnit.toDown(blockUnits, max_y, allBlockUnits);
                        yy = yy + DigitalBlockUnit.UNIT_SIZE;
                    } else {
                        /**
                         * 当不可以继续下落的时候，把当前的方块添加到allBlockUnits中，
                         * 并且判断是否有需要消除的方块，然后再产生一个新的方块
                         */
                        for (DigitalBlockUnit blockUnit : blockUnits) {
                            blockUnit.y = blockUnit.y + DigitalBlockUnit.UNIT_SIZE;
                            allBlockUnits.add(blockUnit);
                        }
                        for (DigitalBlockUnit u : blockUnits) {
                            // 更新map，即更新每行网格中静止俄罗斯方块单元的个数
                            int index = (int) ((u.y - beginPoint) / 206); // 计算所在行数
                            map[index]++;
                        }
                        // 每行最大个数
                        int end = (int) ((max_y - 206 - beginPoint) / DigitalBlockUnit.UNIT_SIZE);
                        int full = (int) ((max_x - 206 - beginPoint) / DigitalBlockUnit.UNIT_SIZE) + 1;
                        try {
                            Thread.sleep(GameConfig.SPEED);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                       /* for (int i = 0; i <= end; i++) {
                            *//***
                         * 消除需要消除的方块（触发条件，某一行中被塞满了方块，没有空白）
                         * 注意顺序，先消除某一行，再移动这一行上边的方块
                         *//*
                            if (map[i] >= full) {
                                DigitalBlockUnit.remove(allBlockUnits, i);
                                score += 100;
                                map[i] = 0;
                                for (int j = i; j > 0; j--)
                                    map[j] = map[j - 1];
                                map[0] = 0;
                                for (DigitalBlockUnit blockUnit : allBlockUnits) {
                                    if (blockUnit.y < (i * DigitalBlockUnit.UNIT_SIZE + beginPoint)) {
                                        blockUnit.y = blockUnit.y + DigitalBlockUnit.UNIT_SIZE;
                                    }
                                }
                            }
                        }*/
                        father.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                /**
                                 * 刷新分数
                                 */
                                // father.score.setText("" + score);
                                invalidate();
                            }
                        });
                        try {
                            Thread.sleep(GameConfig.SPEED * 10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        father.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                getNewBlock();
                                score += 10;
                                //father.score.setText("" + score);
                            }
                        });
                    }
                    father.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            invalidate();
                        }
                    });
                    try {
                        Thread.sleep(GameConfig.SPEED);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }

        }

    }

}
